
#ifndef _TILES_H_
#define _TILES_H_

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
//#include <unistd.h>

namespace planning{
	namespace sarsa{

#define MAX_NUM_VARS 20        // Maximum number of variables in a grid-tiling      
#define MAX_NUM_COORDS 100     // Maximum number of hashing coordinates      
#define MaxLONGINT 2147483647  

void tiles(
	int the_tiles[],               // provided array contains returned tiles (tile indices)
	int num_tilings,           // number of tile indices to be returned in tiles       
    int memory_size,           // total number of possible tiles
	double doubles[],            // array of doubleing point variables
    int num_doubles,            // number of doubleing point variables
    int ints[],				  // array of integer variables
    int num_ints);             // number of integer variables

class collision_table {
public:
    collision_table(int,int);
    ~collision_table();
    long m;
    long *data;
    int safe;
    long calls;
    long clearhits;
    long collisions;
    void reset();
    int usage();
    void print();
    void save(int);
    void restore(int);
};

	
void tiles(
	int the_tiles[],               // provided array contains returned tiles (tile indices)
	int num_tilings,           // number of tile indices to be returned in tiles       
    collision_table *ctable,   // total number of possible tiles
	double doubles[],            // array of doubleing point variables
    int num_doubles,            // number of doubleing point variables
    int ints[],				  // array of integer variables
    int num_ints);             // number of integer variables

int hash_UNH(int *ints, int num_ints, long m, int increment);
int hash(int *ints, int num_ints, collision_table *ctable);

// no ints
void tiles(int the_tiles[],int nt,int memory,double doubles[],int nf);
void tiles(int the_tiles[],int nt,collision_table *ct,double doubles[],int nf);


// one int
void tiles(int the_tiles[],int nt,int memory,double doubles[],int nf,int h1);
void tiles(int the_tiles[],int nt,collision_table *ct,double doubles[],int nf,int h1);

// two ints
void tiles(int the_tiles[],int nt,int memory,double doubles[],int nf,int h1,int h2);
void tiles(int the_tiles[],int nt,collision_table *ct,double doubles[],int nf,int h1,int h2);

// three ints
void tiles(int the_tiles[],int nt,int memory,double doubles[],int nf,int h1,int h2,int h3);
void tiles(int the_tiles[],int nt,collision_table *ct,double doubles[],int nf,int h1,int h2,int h3);

// one double, no ints
void tiles1(int the_tiles[],int nt,int memory,double f1);
void tiles1(int the_tiles[],int nt,collision_table *ct,double f1);

// one double, one int
void tiles1(int the_tiles[],int nt,int memory,double f1,int h1);
void tiles1(int the_tiles[],int nt,collision_table *ct,double f1,int h1);

// one double, two ints
void tiles1(int the_tiles[],int nt,int memory,double f1,int h1,int h2);
void tiles1(int the_tiles[],int nt,collision_table *ct,double f1,int h1,int h2);

// one double, three ints
void tiles1(int the_tiles[],int nt,int memory,double f1,int h1,int h2,int h3);
void tiles1(int the_tiles[],int nt,collision_table *ct,double f1,int h1,int h2,int h3);

// two doubles, no ints
void tiles2(int the_tiles[],int nt,int memory,double f1,double f2);
void tiles2(int the_tiles[],int nt,collision_table *ct,double f1,double f2);

// two doubles, one int
void tiles2(int the_tiles[],int nt,int memory,double f1,double f2,int h1);
void tiles2(int the_tiles[],int nt,collision_table *ct,double f1,double f2,int h1);

// two doubles, two ints
void tiles2(int the_tiles[],int nt,int memory,double f1,double f2,int h1,int h2);
void tiles2(int the_tiles[],int nt,collision_table *ct,double f1,double f2,int h1,int h2);

// two doubles, three ints
void tiles2(int the_tiles[],int nt,int memory,double f1,double f2,int h1,int h2,int h3);
void tiles2(int the_tiles[],int nt,collision_table *ct,double f1,double f2,int h1,int h2,int h3);

void tileswrap(
	int the_tiles[],               // provided array contains returned tiles (tile indices)
	int num_tilings,           // number of tile indices to be returned in tiles       
    int memory_size,           // total number of possible tiles
	double doubles[],            // array of doubleing point variables
    int num_doubles,            // number of doubleing point variables
    int wrap_widths[],         // array of widths (length and units as in doubles)
    int ints[],				  // array of integer variables
    int num_ints);             // number of integer variables
	
void tileswrap(
	int the_tiles[],               // provided array contains returned tiles (tile indices)
	int num_tilings,           // number of tile indices to be returned in tiles       
    collision_table *ctable,   // total number of possible tiles
	double doubles[],            // array of doubleing point variables
    int num_doubles,            // number of doubleing point variables
    int wrap_widths[],         // array of widths (length and units as in doubles)
    int ints[],				  // array of integer variables
    int num_ints);             // number of integer variables

}
}


#endif
